//
//  CardScrollView.m
//  3dtest
//
//  Created by XL on 2022/7/21.
//



#import "CardScrollView.h"
#import "Masonry.h"



@interface CardScrollView()

@property (nonatomic , nonnull , strong) NSArray<NSString *> * sources;

@property (nonatomic , nonnull , strong) UIView * contentView;

///手势开始原点
@property (nonatomic , assign) CGPoint  gestureOrigin;

///手势开始scrollviewX点
@property (nonatomic , assign) CGPoint  currentScrollPanGestureContentOffset;

///一页的距离
@property (nonatomic , assign) CGFloat  pageWidth;

///当前页码
@property (nonatomic , assign) int  currentPageIndex;

///记录滑动比例
@property (nonatomic , assign) CGFloat  scrollRate;

@end

@implementation CardScrollView


- (UIView *)contentView{
    if (_contentView == nil) {
        _contentView = [UIView new];
    }
    return _contentView;
}


- (instancetype)initWithSource:(NSArray<NSString *> *)sources{
    if (self = [super initWithFrame:CGRectZero]) {
        self.sources = [sources copy];
        self.scrollEnabled = NO;
        self.showsVerticalScrollIndicator = NO;
        self.showsHorizontalScrollIndicator = NO;
        self.scrollRate = 0;
        self.currentPageIndex = 0;
        self.currentScrollPanGestureContentOffset = CGPointZero;
        self.pageWidth = /*第一个item距离左边间距*/cardLeftSpace + [CardItemView cardWidth] - /*间距*/cardItemSpace;
        [self buildUI];
    }
    return self;
}

- (void)buildUI {
    
    [self addSubview:self.contentView];
    [self.contentView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self);
        make.height.equalTo(@([CardItemView cardHeight]));
    }];

    for (int i = 0; i < self.sources.count ; i ++) {
        CardItemView * itemv = [[CardItemView alloc] initWithFilePath:self.sources[i]];
        itemv.tag = 100 + i;
        [self.contentView addSubview:itemv];
        [itemv mas_makeConstraints:^(MASConstraintMaker *make) {
            make.width.equalTo(@([CardItemView cardWidth]));
            make.height.equalTo(@([CardItemView cardHeight]));
            make.top.bottom.equalTo(self);
            if (i == 0) {
                make.leading.equalTo(@(cardLeftSpace));
            }else {
                CardItemView * before = [self.contentView viewWithTag:100 + i - 1];
                make.leading.equalTo(before.mas_trailing).offset(cardItemSpace);
            }
            if (i == self.sources.count - 1) {
                make.trailing.equalTo(self).offset(-cardLeftSpace);
            }
        }];
        //卡片点击事件
        __weak CardScrollView * weakSelf = self;
        __weak CardItemView * weakCard = itemv;
        itemv.clickBlock = ^{
            [weakCard flipViewByRate:i > self.currentPageIndex ? -1 : 1];
            [weakSelf setIndex:i byScrolling:NO];
        };
        if (i % 2 == 1) {
            itemv.currentRotationY = -M_PI;
            [itemv.scnView.scene.rootNode runAction:[SCNAction rotateToX:0 y:itemv.currentRotationY z:0 duration:0] completionHandler:^{
            }];
        }
        
    }
    
    UIPanGestureRecognizer * pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
    [self.contentView addGestureRecognizer:pan];
}


- (void)panGesture:(UIPanGestureRecognizer *)gesture {
    UIWindow * window = [[[UIApplication sharedApplication] windows] objectAtIndex:0];
    CGFloat rate = [gesture translationInView:window].x / window.frame.size.width;//滑动的比例
    CGFloat velocity = fabs([gesture velocityInView:window].x);//滑动的速率
    
    switch (gesture.state) {
        case UIGestureRecognizerStateBegan:{//记录手势开始时的，手势在window视图的坐标
            self.gestureOrigin = [gesture locationInView:window];
            break;
        }
        case UIGestureRecognizerStateChanged:{//手势滑动时改变scrollview的contentOffset和卡片翻转
            //记录一个方向滑动的最大比例
            if (self.scrollRate == 0 && rate != 0) {
                self.scrollRate = rate;
            }else{
                if (self.scrollRate > 0 && rate > self.scrollRate) {//是手往右划，上一页
                    self.scrollRate = rate;
                }else if(self.scrollRate < 0 && rate < self.scrollRate){//是手往左划，下一页
                    self.scrollRate = rate;
                }
            }
            
            
            CGPoint currentOrigin = [gesture locationInView:window];
            CGFloat diffX = currentOrigin.x - self.gestureOrigin.x;
            if ((fabs(diffX) > self.pageWidth)) {//滑动距离不超过一页
                return;
            }
            
            CGFloat newOffset = diffX > 0 ? -diffX : fabs(diffX);
            self.contentOffset = CGPointMake(self.currentScrollPanGestureContentOffset.x + newOffset, 0);
            
            if (rate == 0) {
                return;
            }
            for (int i = 0; i < self.sources.count; i ++) {
                CardItemView * item = (CardItemView *)[self.contentView viewWithTag:100 + i];
                [item animationToRatio:rate];
            }
            break;
        }
        case UIGestureRecognizerStateEnded:{//手势结束时，处理是要切换页码还是回到当前页
            self.gestureOrigin = CGPointZero;
#pragma mark - 这里可以优化，当我先划下一页到80%，然后又往回划10%，现在值是70%，但因为滑动的比例大于10%还是触发了切换下一页(√)
            
            if (self.scrollRate > 0) {//是手往右划，上一页
                if (rate < self.scrollRate) {//用户又突然往左划，这时候取消翻页
                    [self animationEnd:NO rate:rate];
                    return;
                }
            }else{//是手往左划，下一页
                if (rate > self.scrollRate) {//用户又突然往右划，这时候取消翻页
                    [self animationEnd:NO rate:rate];
                    return;
                }
            }
            
            if (fabs(rate) >= 0.1){
                [self animationEnd:YES rate:rate];
            }else{
                if (velocity > 920) {
                    [self animationEnd:YES rate:rate];
                }else{
                    [self animationEnd:NO rate:rate];
                }
            }
            break;
        }
            
        default:
            break;
    }
}

/// 手势结束是否翻页
/// @param isEnd 是否翻页
/// @param rate 用来判断方向
- (void)animationEnd:(BOOL)isEnd rate:(CGFloat)rate {
    self.scrollRate = 0;
    if (self.contentOffset.x == self.currentScrollPanGestureContentOffset.x) {
        self.contentOffset = self.currentScrollPanGestureContentOffset;
        return;
    }
    if (self.currentPageIndex == 0 && self.contentOffset.x < 0) {//是在第一页，手且往右滑
        [self setContentOffset:self.currentScrollPanGestureContentOffset animated:YES];
        for (int i = 0; i < self.sources.count; i ++) {
            CardItemView * item = (CardItemView *)[self.contentView viewWithTag:100 + i];
            [item animationToRatio:rate status:NO isCurrent:i == self.currentPageIndex];
        }
        return;
    }
    if (self.currentPageIndex == self.sources.count - 1 && self.contentOffset.x > self.currentScrollPanGestureContentOffset.x) {//是在最后一页，手且往左滑
        [self setContentOffset:self.currentScrollPanGestureContentOffset animated:YES];
        for (int i = 0; i < self.sources.count; i ++) {
            CardItemView * item = (CardItemView *)[self.contentView viewWithTag:100 + i];
            [item animationToRatio:rate status:NO isCurrent:i == self.currentPageIndex];
        }
        return;
    }
    BOOL isNext = self.contentOffset.x >= self.currentScrollPanGestureContentOffset.x;
    if (isEnd) {
        int newPage = isNext ? self.currentPageIndex + 1 : self.currentPageIndex - 1;
        newPage = newPage < 0 ? 0 : newPage;
        newPage = newPage > self.sources.count - 1 ? (int)(self.sources.count - 1) : newPage;
        [self setIndex:newPage byScrolling:YES];
        for (int i = 0; i < self.sources.count; i ++) {
            CardItemView * item = (CardItemView *)[self.contentView viewWithTag:100 + i];
            [item animationToRatio:rate status:isEnd isCurrent:i == newPage];
        }
    }else{
        [self setContentOffset:self.currentScrollPanGestureContentOffset animated:YES];
        for (int i = 0; i < self.sources.count; i ++) {
            CardItemView * item = (CardItemView *)[self.contentView viewWithTag:100 + i];
            [item animationToRatio:rate > 0 status:isEnd isCurrent:NO];
        }
    }
}

/// 点击卡片或者触发翻页时切换页码下标和（移动\回到）新页码的位置
/// @param index 新页码
/// @param isScrolling 通过滑动个切换页
- (void)setIndex:(int)index byScrolling:(BOOL)isScrolling {
    if (self.changePageBlock != nil && self.currentPageIndex != index) {
        self.changePageBlock(index);
    }
    if (isScrolling == NO && self.currentPageIndex != index) {
        for (int i = 0; i < self.sources.count; i ++) {
            if (index == i) {
                continue;
            }
            CardItemView * item = (CardItemView *)[self.contentView viewWithTag:100 + i];
            [item animationToRatio:index > self.currentPageIndex ? -1 : 1 status:true isCurrent:NO];
        }
    }
    self.currentPageIndex = index;
    CGPoint offset = CGPointMake(index * self.pageWidth, 0);
    [self setContentOffset:offset animated:YES];
    self.currentScrollPanGestureContentOffset = offset;
    
    
}

@end
